"""
扩展API接口
实现AI分析、任务管理、设备管理、导出等功能的API端点
"""
from fastapi import APIRouter, HTTPException, Depends, Query, Path, Body
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import List, Optional, Dict, Any
from datetime import datetime, timedelta
import logging

from .models import *
from .ai_service import AIService
from .export_service import ExportService
from .task_service import TaskService, TaskBoardService
from .device_service import DeviceService
from .visualization_service import VisualizationService

logger = logging.getLogger(__name__)

# 创建路由器
router = APIRouter(prefix="/api/v2", tags=["Extended Features"])

# 安全认证
security = HTTPBearer()

# 服务实例
ai_service = AIService()
export_service = ExportService()
task_service = TaskService()
task_board_service = TaskBoardService(task_service)
device_service = DeviceService()
visualization_service = VisualizationService()


def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
    """获取当前用户（简化实现）"""
    # 这里应该验证JWT token并返回用户ID
    # 简化实现：直接返回用户ID
    return "user_001"


def get_current_team(user_id: str = Depends(get_current_user)) -> str:
    """获取当前用户团队（简化实现）"""
    # 这里应该从数据库查询用户所属团队
    # 简化实现：直接返回团队ID
    return "team_001"


# ==================== AI分析相关API ====================

@router.post("/ai/analyze", response_model=AIAnalysisOut)
async def analyze_signal_data(
    analysis_request: AIAnalysisIn,
    user_id: str = Depends(get_current_user)
):
    """AI信号分析"""
    try:
        result = ai_service.analyze_signal_data(analysis_request)
        return result
    except Exception as e:
        logger.error(f"AI分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"AI分析失败: {str(e)}")


@router.post("/ai/batch-analyze", response_model=List[AIAnalysisOut])
async def batch_analyze_signal_data(
    analysis_requests: List[AIAnalysisIn],
    user_id: str = Depends(get_current_user)
):
    """批量AI分析"""
    try:
        if len(analysis_requests) > 100:
            raise HTTPException(status_code=400, detail="批量分析数量不能超过100个")
        
        results = ai_service.batch_analyze(analysis_requests)
        return results
    except Exception as e:
        logger.error(f"批量AI分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"批量AI分析失败: {str(e)}")


# ==================== 任务管理相关API ====================

@router.post("/tasks", response_model=TaskOut)
async def create_task(
    task_data: TaskIn,
    user_id: str = Depends(get_current_user)
):
    """创建任务"""
    try:
        task = task_service.create_task(task_data, user_id)
        return task
    except Exception as e:
        logger.error(f"任务创建失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"任务创建失败: {str(e)}")


@router.get("/tasks/{task_id}", response_model=TaskOut)
async def get_task(
    task_id: str = Path(..., description="任务ID"),
    user_id: str = Depends(get_current_user)
):
    """获取任务详情"""
    task = task_service.get_task(task_id, user_id)
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在")
    return task


@router.put("/tasks/{task_id}", response_model=TaskOut)
async def update_task(
    task_id: str = Path(..., description="任务ID"),
    task_update: TaskUpdate = Body(...),
    user_id: str = Depends(get_current_user)
):
    """更新任务"""
    task = task_service.update_task(task_id, task_update, user_id)
    if not task:
        raise HTTPException(status_code=404, detail="任务不存在或无权限")
    return task


@router.delete("/tasks/{task_id}")
async def delete_task(
    task_id: str = Path(..., description="任务ID"),
    user_id: str = Depends(get_current_user)
):
    """删除任务"""
    success = task_service.delete_task(task_id, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="任务不存在或无权限")
    return {"message": "任务删除成功"}


@router.get("/tasks", response_model=Dict[str, Any])
async def get_team_tasks(
    status: Optional[TaskStatus] = Query(None, description="任务状态"),
    assignee_id: Optional[str] = Query(None, description="分配者ID"),
    priority: Optional[TaskPriority] = Query(None, description="优先级"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取团队任务列表"""
    result = task_service.get_team_tasks(
        team_id, user_id, status, assignee_id, priority, page, page_size
    )
    return result


@router.get("/tasks/my", response_model=Dict[str, Any])
async def get_my_tasks(
    status: Optional[TaskStatus] = Query(None, description="任务状态"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    user_id: str = Depends(get_current_user)
):
    """获取我的任务列表"""
    result = task_service.get_user_tasks(user_id, status, page, page_size)
    return result


@router.get("/tasks/statistics", response_model=Dict[str, Any])
async def get_task_statistics(
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取任务统计信息"""
    stats = task_service.get_task_statistics(team_id, user_id)
    return stats


@router.get("/tasks/board", response_model=Dict[str, Any])
async def get_task_board(
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取任务看板"""
    board = task_board_service.get_task_board(team_id, user_id)
    return board


@router.put("/tasks/{task_id}/move")
async def move_task(
    task_id: str = Path(..., description="任务ID"),
    new_status: TaskStatus = Body(..., description="新状态"),
    user_id: str = Depends(get_current_user)
):
    """移动任务状态"""
    success = task_board_service.move_task(task_id, new_status, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="任务不存在或无权限")
    return {"message": "任务状态更新成功"}


@router.post("/tasks/{task_id}/comments", response_model=TaskCommentOut)
async def add_task_comment(
    task_id: str = Path(..., description="任务ID"),
    comment_data: TaskCommentIn = Body(...),
    user_id: str = Depends(get_current_user)
):
    """添加任务评论"""
    comment = task_service.add_task_comment(comment_data, user_id)
    if not comment:
        raise HTTPException(status_code=404, detail="任务不存在或无权限")
    return comment


@router.get("/tasks/{task_id}/comments", response_model=List[TaskCommentOut])
async def get_task_comments(
    task_id: str = Path(..., description="任务ID"),
    user_id: str = Depends(get_current_user)
):
    """获取任务评论"""
    comments = task_service.get_task_comments(task_id, user_id)
    return comments


# ==================== 设备管理相关API ====================

@router.post("/devices", response_model=DeviceOut)
async def register_device(
    device_data: DeviceIn,
    user_id: str = Depends(get_current_user)
):
    """注册设备"""
    try:
        device = device_service.register_device(device_data, user_id)
        return device
    except Exception as e:
        logger.error(f"设备注册失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"设备注册失败: {str(e)}")


@router.get("/devices/{device_id}", response_model=DeviceOut)
async def get_device(
    device_id: str = Path(..., description="设备ID"),
    user_id: str = Depends(get_current_user)
):
    """获取设备信息"""
    device = device_service.get_device(device_id, user_id)
    if not device:
        raise HTTPException(status_code=404, detail="设备不存在")
    return device


@router.put("/devices/{device_id}/status", response_model=DeviceOut)
async def update_device_status(
    device_id: str = Path(..., description="设备ID"),
    status_update: DeviceStatusUpdate = Body(...),
    user_id: str = Depends(get_current_user)
):
    """更新设备状态"""
    device = device_service.update_device_status(status_update, user_id)
    if not device:
        raise HTTPException(status_code=404, detail="设备不存在或无权限")
    return device


@router.get("/devices", response_model=Dict[str, Any])
async def get_team_devices(
    status: Optional[DeviceStatus] = Query(None, description="设备状态"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取团队设备列表"""
    result = device_service.get_team_devices(team_id, user_id, status, page, page_size)
    return result


@router.get("/devices/{device_id}/status-history", response_model=List[Dict[str, Any]])
async def get_device_status_history(
    device_id: str = Path(..., description="设备ID"),
    hours: int = Query(24, ge=1, le=168, description="历史小时数"),
    user_id: str = Depends(get_current_user)
):
    """获取设备状态历史"""
    history = device_service.get_device_status_history(device_id, user_id, hours)
    return history


@router.get("/devices/{device_id}/statistics", response_model=DeviceStats)
async def get_device_statistics(
    device_id: str = Path(..., description="设备ID"),
    user_id: str = Depends(get_current_user)
):
    """获取设备统计信息"""
    stats = device_service.get_device_statistics(device_id, user_id)
    if not stats:
        raise HTTPException(status_code=404, detail="设备不存在")
    return stats


@router.get("/devices/{device_id}/config", response_model=Dict[str, Any])
async def get_device_config(
    device_id: str = Path(..., description="设备ID"),
    user_id: str = Depends(get_current_user)
):
    """获取设备配置"""
    config = device_service.get_device_config(device_id, user_id)
    if config is None:
        raise HTTPException(status_code=404, detail="设备不存在")
    return config


@router.put("/devices/{device_id}/config")
async def update_device_config(
    device_id: str = Path(..., description="设备ID"),
    config: Dict[str, Any] = Body(...),
    user_id: str = Depends(get_current_user)
):
    """更新设备配置"""
    success = device_service.update_device_config(device_id, config, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="设备不存在或无权限")
    return {"message": "设备配置更新成功"}


@router.get("/devices/offline", response_model=List[DeviceOut])
async def get_offline_devices(
    offline_threshold_minutes: int = Query(30, ge=5, le=1440, description="离线阈值(分钟)"),
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取离线设备列表"""
    devices = device_service.get_offline_devices(team_id, user_id, offline_threshold_minutes)
    return devices


@router.get("/devices/alerts", response_model=List[Dict[str, Any]])
async def get_device_alerts(
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取设备告警"""
    alerts = device_service.get_device_alerts(team_id, user_id)
    return alerts


# ==================== 数据导出相关API ====================

@router.post("/exports", response_model=ExportRecordOut)
async def export_data(
    export_request: ExportRequest,
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """导出数据"""
    try:
        # 这里应该根据筛选条件查询数据
        # 简化实现：使用模拟数据
        signal_data = self._get_signal_data_for_export(export_request.filter_criteria)
        
        export_record = export_service.export_data(signal_data, export_request, user_id, team_id)
        return export_record
    except Exception as e:
        logger.error(f"数据导出失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"数据导出失败: {str(e)}")


@router.get("/exports", response_model=List[ExportRecordOut])
async def get_export_history(
    limit: int = Query(100, ge=1, le=1000, description="返回数量"),
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取导出历史"""
    history = export_service.get_export_history(user_id, team_id, limit)
    return history


@router.get("/exports/{export_id}/download")
async def download_export_file(
    export_id: str = Path(..., description="导出ID"),
    user_id: str = Depends(get_current_user)
):
    """下载导出文件"""
    file_path = export_service.download_export_file(export_id, user_id)
    if not file_path:
        raise HTTPException(status_code=404, detail="导出文件不存在")
    
    # 这里应该返回文件下载响应
    return {"file_path": file_path}


# ==================== 可视化相关API ====================

@router.post("/visualization/trend", response_model=TrendDataOut)
async def generate_trend_data(
    signal_data: List[Dict[str, Any]] = Body(...),
    metric_name: str = Query("signal_strength", description="指标名称"),
    aggregation_type: str = Query("raw", description="聚合类型"),
    user_id: str = Depends(get_current_user)
):
    """生成趋势图数据"""
    try:
        trend_data = visualization_service.generate_trend_data(
            signal_data, metric_name, aggregation_type
        )
        return trend_data
    except Exception as e:
        logger.error(f"趋势图数据生成失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"趋势图数据生成失败: {str(e)}")


@router.post("/visualization/heatmap", response_model=HeatmapDataOut)
async def generate_heatmap_data(
    signal_data: List[Dict[str, Any]] = Body(...),
    data_type: str = Query("signal_strength", description="数据类型"),
    width: int = Query(100, ge=10, le=1000, description="宽度"),
    height: int = Query(100, ge=10, le=1000, description="高度"),
    color_scheme: str = Query("viridis", description="颜色方案"),
    user_id: str = Depends(get_current_user)
):
    """生成热力图数据"""
    try:
        heatmap_data = visualization_service.generate_heatmap_data(
            signal_data, data_type, width, height, color_scheme
        )
        return heatmap_data
    except Exception as e:
        logger.error(f"热力图数据生成失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"热力图数据生成失败: {str(e)}")


# ==================== 仪表板相关API ====================

@router.get("/dashboard/stats", response_model=DashboardStats)
async def get_dashboard_stats(
    user_id: str = Depends(get_current_user),
    team_id: str = Depends(get_current_team)
):
    """获取仪表板统计信息"""
    try:
        # 获取设备统计
        devices_result = device_service.get_team_devices(team_id, user_id, page_size=1000)
        total_devices = devices_result['total']
        active_devices = len([d for d in devices_result['devices'] if d.status == DeviceStatus.ACTIVE])
        
        # 获取任务统计
        task_stats = task_service.get_task_statistics(team_id, user_id)
        
        # 获取导出统计
        export_history = export_service.get_export_history(user_id, team_id, 1000)
        
        stats = DashboardStats(
            total_devices=total_devices,
            active_devices=active_devices,
            total_tasks=task_stats.get('total_tasks', 0),
            pending_tasks=task_stats.get('pending_tasks', 0),
            completed_tasks=task_stats.get('completed_tasks', 0),
            total_exports=len(export_history),
            total_users=10,  # 模拟数据
            team_count=1  # 模拟数据
        )
        
        return stats
    except Exception as e:
        logger.error(f"获取仪表板统计失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取仪表板统计失败: {str(e)}")


# ==================== 辅助方法 ====================

def _get_signal_data_for_export(filter_criteria: Dict[str, Any]) -> List[Dict[str, Any]]:
    """获取用于导出的信号数据（模拟实现）"""
    # 这里应该根据筛选条件从数据库查询数据
    # 简化实现：返回模拟数据
    return [
        {
            "device_id": "device_001",
            "signal_strength": -85,
            "latitude": 39.9042,
            "longitude": 116.4074,
            "collected_at": datetime.utcnow().isoformat(),
            "network_type": "LTE",
            "operator_name": "中国移动"
        }
    ]